package me.lc.hammerheads.core;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;

import me.lc.hammerheads.entity.GameStageInfo;
import me.lc.hammerheads.entity.HoleLocationInfo;
import me.lc.hammerheads.layer.GameLayer;
import me.lc.hammerheads.sprite.Dwarf;
import me.lc.hammerheads.sprite.Hole;
import me.lc.hammerheads.sprite.dwarfUnit.DwarfBomb;
import me.lc.hammerheads.sprite.dwarfUnit.DwarfFemale;
import me.lc.hammerheads.sprite.dwarfUnit.DwarfHatMan;
import me.lc.hammerheads.sprite.dwarfUnit.DwarfLuckDuck;
import me.lc.hammerheads.sprite.dwarfUnit.DwarfNormal;
import me.lc.hammerheads.sprite.dwarfUnit.DwarfSilver;

import com.wiyun.engine.nodes.Scheduler;
import com.wiyun.engine.nodes.Timer;
import com.wiyun.engine.types.WYPoint;
import com.wiyun.engine.utils.ResolutionIndependent;
import com.wiyun.engine.utils.TargetSelector;

public class GameMap {
	public static GameMap instance = new GameMap();
	private Object sync_obj = new Object();

	private GameMap() {
		init();
	}

	/**
	 */
	private void init() {
		holeList = new CopyOnWriteArrayList<Hole>();
		dwarfLst = new CopyOnWriteArrayList<Dwarf>();
		readyDwarfQueue = new ConcurrentLinkedQueue<Dwarf>();
		dwarfHoleMap = new ConcurrentHashMap<Dwarf, Hole>();
		currentDwarfLst = new ConcurrentLinkedQueue<Dwarf>();
		r = new Random((new Date()).getTime());
		ts = new TargetSelector(this, "dwarfActionTask(float)",
				new Object[] { 0f });
	}

	TargetSelector ts;

	GameLayer gameLayer;
	// 所有的hole列表
	CopyOnWriteArrayList<Hole> holeList;
	// 已经显示的矮人列表
	CopyOnWriteArrayList<Dwarf> dwarfLst;
	// 已经显示的矮人队列
	ConcurrentLinkedQueue<Dwarf> currentDwarfLst;
	// 准备显示的矮人列表
	ConcurrentLinkedQueue<Dwarf> readyDwarfQueue;
	// 矮人和hole的关联
	ConcurrentHashMap<Dwarf, Hole> dwarfHoleMap;
	Timer dwarfActionTimer;
	Random r;

	public void gen(GameLayer gameLayer, GameStageInfo stage) {
		currentDwarfLst.clear();
		holeList.clear();
		dwarfLst.clear();
		readyDwarfQueue.clear();
		dwarfHoleMap.clear();
		this.gameLayer = gameLayer;
		for (HoleLocationInfo holeInfo : stage.getHoles()) {
			// 增加holes
			Hole hole = new Hole();
			float x = GameSystem.Screen_Width * holeInfo.getPercentX();
			float y = GameSystem.Screen_Height * holeInfo.getPercentY();
			hole.setPosition(x, y);
			holeList.add(hole);
			gameLayer.addChild(hole, 1);
			// 设置hole为空
			hole.setEmpty(true);

		}
		// 矮人检测Timer
		if (dwarfActionTimer != null) {
			Scheduler.getInstance().unschedule(dwarfActionTimer);
			dwarfActionTimer = null;
		}
		dwarfActionTimer = new Timer(ts, 0.1f);
		Scheduler.getInstance().schedule(dwarfActionTimer);
		// dwarfActionTimer.schedule(new DwarfActionTask(), 100, 100);
	}

	public synchronized void knockOutAllDwarf() {
		synchronized (sync_obj) {
			for (Dwarf dwarf : dwarfLst) {
				if (dwarf.isAlived()) {
					dwarf.knockOut();
				}
			}
		}

	}

	public synchronized void pauseAllDwarf() {
		synchronized (sync_obj) {
			for (Dwarf dwarf : dwarfLst) {
				if (dwarf.isAlived()) {
					dwarf.pauseAllActions(true);
				}
			}
		}
	}

	public synchronized void resumeAllDwarf() {
		synchronized (sync_obj) {
			for (Dwarf dwarf : dwarfLst) {
				if (dwarf.isAlived()) {
					dwarf.resumeAllActions(true);
				}
			}
		}
	}

	/**
	 * 
	 * @param point
	 * @return 返回打击类型 0.没打中 1.成功打中矮人 2.打中物件 3.打击矮人失败
	 */
	public int hit(WYPoint point) {
		for (Dwarf dwarf : dwarfLst) {
			if (dwarf.isAlived() && dwarf.isHit(point)
					&& !dwarf.isKnockingout()) {

				int power = 1;
				if (GameManager.instance.getDoubleHammerCount() > 0) {
					power = 2;
					GameManager.instance.addDoubleHammerCount(-1);
				}
				int result = dwarf.knock(power);
				if (result == 1) {
					GameManager.instance.knockResult(true);
					return 1;
				} else {
					GameManager.instance.knockResult(false);
					return 3;
				}
			}
		}
		// 扣血
		GameManager.instance.changeGameHeart(false);

		// 统计
		GameManager.instance.knockResult(false);
		return 0;
	}

	/**
	 * 测试是否点中了东西 如果能够打中，返回大众的位置 如果没能命中，返回null
	 * 
	 * @param point
	 * @return
	 */
	public WYPoint testHit(WYPoint point) {
		WYPoint result = null;
		for (Dwarf dwarf : dwarfLst) {
			if (dwarf.isAlived() && dwarf.isHit(point)) {
				result = WYPoint.make(dwarf.getPositionX(),
						dwarf.getPositionY()
								+ (GameSystem.tex_man1.getHeight() / 2)
								- ResolutionIndependent.resolveDp(4));
				break;
			}
		}
		return result;
	}

	/**
	 * 根据hole的位置获取矮人的位置
	 * 
	 * @param x
	 * @param y
	 * @return
	 */
	private WYPoint getDwarfPoint(float x, float y) {
		float xDwarf = x;
		float yDwarf = y + GameSystem.tex_man1.getHeight() / 2
				- ResolutionIndependent.resolveDp(7);
		WYPoint dwarfPoint = WYPoint.make(xDwarf, yDwarf);
		return dwarfPoint;
	}

	/**
	 * 新增一个矮人
	 * 
	 * @param dwarfType
	 *            1-5 矮人 101鸭子
	 */
	public void addNewDwarf(int dwarfType) {

		boolean hasEmpty = false;
		for (Hole hole : holeList) {
			if (hole.isEmpty()) {
				hasEmpty = true;
				break;
			}
		}
		if (!hasEmpty) {
			// 从当前队列里面找到第一个矮人，调用drillHide
			Dwarf hideOne = currentDwarfLst.peek();
			if (hideOne != null) {
				hideOne.drillHide();
			}
		}
		// 加入队列，交给监视器处理
		Dwarf dwarf = null;
		switch (dwarfType) {
		case 1:
			dwarf = new DwarfNormal();
			break;
		case 2:
			dwarf = new DwarfFemale();
			break;
		case 3:
			dwarf = new DwarfHatMan();
			break;
		case 4:
			dwarf = new DwarfBomb();
			break;
		case 5:
			dwarf = new DwarfSilver();
			break;
		case 101:
			dwarf = new DwarfLuckDuck();
			break;
		}
		if (dwarf != null) {
			readyDwarfQueue.add(dwarf);
		}
	}

	public void dwarfActionTask(float value) {
		synchronized (sync_obj) {

			// 清空已经没用的矮人实例
			List<Dwarf> deleteList = new ArrayList<Dwarf>();
			for (Dwarf dwarf : dwarfLst) {
				if (!dwarf.isAlived()) {
					deleteList.add(dwarf);
				}
			}
			for (Dwarf dwarf : deleteList) {
				if (dwarfHoleMap.containsKey(dwarf)) {
					dwarfHoleMap.get(dwarf).setEmpty(true);
					dwarfHoleMap.remove(dwarf);
				}
				dwarfLst.remove(dwarf);
				currentDwarfLst.remove(dwarf);
				if (dwarf != null) {
					// 强行设置为不可见
					dwarf.setVisible(false);
					gameLayer.removeChild(dwarf, false);
				}
			}

			// TODO lc 估计要换个方法，不能一直调用
			Dwarf dwarf = readyDwarfQueue.peek();
			if (dwarf != null) {
				// 1.找到可用的hole的集合
				// 1-1.如果有可用的hole，随机加载到一个hole中
				// 1-2.如果没有可用的hole，drillhide其中的矮人，等到完成动画后完成矮人加载

				List<Hole> emptyHole = new ArrayList<Hole>(5);
				for (Hole hole : holeList) {
					if (hole.isEmpty()) {
						emptyHole.add(hole);
					}
				}
				if (emptyHole.size() > 0) {
					// 有空的hole,随机获取一个洞
					int holeIndex = r.nextInt(emptyHole.size());
					Hole selectHole = emptyHole.get(holeIndex);

					dwarf.setPosition(getDwarfPoint(selectHole.getPositionX(),
							selectHole.getPositionY()));
					gameLayer.addChild(dwarf, 2);
					dwarfLst.add(dwarf);
					dwarf.drillShow();
					selectHole.setEmpty(false);

					readyDwarfQueue.poll();
					dwarfLst.add(dwarf);
					currentDwarfLst.add(dwarf);
					dwarfHoleMap.put(dwarf, selectHole);
				}
			}
		}

	}
}
